import { useEffect, useState } from 'react';
import { getApi, postApi } from '@/api/index';
import { API_RESULT } from '@/const';
import { getLocal, saveLocal } from '@/utils';
import { message } from 'antd';

export interface IUseDatabaseOptions {
  /** get数据列表的接口名称 */
  getUrl?: string;
  /** 触发get方法的依赖项 */
  getDep?: any[];
  /** get方法执行时需要的参数（使用方法实现动态） */
  getParams?: () => Record<string, any>;
  /** getData后的映射方法 */
  dataMapper?: (v: any) => any;
  /** 是否初始化时就使用getData */
  init?: boolean;
  /** 使用上次访问对象记忆功能时，需要的local存储key */
  restoreKey?: string;
  createUrl?: string;
  removeUrl?: string;
  updateUrl?: string;
}

export const useDatabase = <T>(opts: IUseDatabaseOptions) => {
  const {
    init = false,
    getDep = [],
    getUrl,
    createUrl,
    removeUrl,
    updateUrl,
    getParams,
    dataMapper,
    restoreKey = '',
  } = opts;

  const [data, setData] = useState<T[]>();
  const [activeTarget, setActiveTarget] = useState<T | null>(null);

  useEffect(() => {
    if (init) {
      const params = getParams?.() || {};
      getData(params).then((resData) => {
        if (resData) {
          setData(resData);
        }
      });
      return;
    }
  }, getDep);

  useEffect(() => {
    // @ts-ignore
    if (!restoreKey || !activeTarget?.id) {
      return;
    }
    if (activeTarget) {
      // @ts-ignore
      saveLocal(restoreKey, activeTarget.id);
    } else {
      saveLocal(restoreKey, '');
    }
  }, [activeTarget]);

  const getData = (params?: Record<string, string | number>) => {
    if (!getUrl) {
      console.warn('缺少api配置');
      return Promise.reject('缺少api配置');
    }
    return getApi(getUrl, params || {})
      .then((res) => {
        if (res.code === API_RESULT.SUCCESS) {
          let list = [];
          if (dataMapper) {
            list = res.data.map(dataMapper) as T[];
          } else {
            list = res.data as T[];
          }
          if (restoreKey) {
            const restoreId = getLocal(restoreKey, '');
            if (restoreId) {
              const restoreItem = list.find(
                (i: any) => i.id === restoreId,
              ) as T;
              setActiveTarget(restoreItem || null);
            } else {
              setActiveTarget(list?.[0] || null);
            }
          }
          return list;
        }
      })
      .catch((e) => {
        console.warn(`接口异常=> ${getUrl}`);
        setData([]);
      });
  };

  const createDataApi = (params: Record<string, string | number>) => {
    const url = createUrl;
    if (!url) {
      console.warn('缺少api配置');
      return Promise.reject('缺少api配置');
    }
    return postApi(url, params || {})
      .then((res) => {
        if (res.code === API_RESULT.SUCCESS) {
          return res.data as T[];
        }
        return [] as T[];
      })
      .catch((e) => {
        message.warn(`接口异常=> ${url}`);
        console.warn(`接口异常=> ${url}`);
      });
  };

  const updateDataApi = (params: Record<string, string | number>) => {
    const url = updateUrl;
    if (!url) {
      console.warn('缺少api配置');
      return Promise.reject('缺少api配置');
    }
    return postApi(url, params || {})
      .then((res) => {
        if (res.code === API_RESULT.SUCCESS) {
          return true;
        }
        return false;
      })
      .catch((e) => {
        message.warn(`接口异常=> ${url}`);
        console.warn(`接口异常=> ${url}`);
      });
  };

  const removeDataApi = (params: Record<string, string | number>) => {
    const url = removeUrl;
    if (!url) {
      console.warn('缺少api配置');
      return Promise.reject('缺少api配置');
    }
    return postApi(url, params || {})
      .then((res) => {
        if (res.code === API_RESULT.SUCCESS) {
          return true;
        }
        return false;
      })
      .catch((e) => {
        message.warn(`接口异常=> ${url}`);
        console.warn(`接口异常=> ${url}`);
      });
  };

  const create = (params: T) => {
    const _params = params as unknown as Record<string, string | number>;
    return createDataApi(_params).then((data) => {
      if (!data) {
        return Promise.reject('');
      }
      if (restoreKey) {
        saveLocal(restoreKey, _params.id || '');
      }
      const gParams = getParams?.() || {};
      getData(gParams).then((resData) => {
        if (resData) {
          setData(resData);
        }
      });
    });
  };

  const remove = (params: T) => {
    const _params = params as unknown as Record<string, string | number>;
    return removeDataApi(_params).then((data) => {
      if (!data) {
        return Promise.reject('');
      }
      if (restoreKey) {
        saveLocal(restoreKey, '');
      }
      const gParams = getParams?.() || {};
      getData(gParams).then((resData) => {
        if (resData) {
          setData(resData);
        }
      });
    });
  };

  const update = (params: T) => {
    const _params = params as unknown as Record<string, string | number>;
    return updateDataApi(_params).then((data) => {
      if (!data) {
        return Promise.reject('');
      }
      const gParams = getParams?.() || {};
      getData(gParams).then((resData) => {
        if (resData) {
          setData(resData);
        }
      });
    });
  };

  return { data, activeTarget, setActiveTarget, create, remove, update };
};
